package cn.by.wms.config;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import cn.hutool.jwt.JWT;
import cn.hutool.jwt.JWTUtil;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
@Configuration
@EnableWebSecurity //开启spring security功能
@EnableGlobalMethodSecurity(prePostEnabled=true,securedEnabled=true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable();//禁止跨站请求伪造
        http.logout().disable();//禁止登录功能
        http.formLogin().disable();//禁止等出功能
        http.sessionManagement().disable();//禁止httpsession

        http.authorizeRequests()
                .antMatchers("/api/user/**").permitAll()
                .anyRequest().authenticated(); // 除了上面的antMatchers配置，剩下的所有请求都需要认证

        http.addFilterBefore(new JwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
    }

    private class JwtAuthenticationFilter extends BasicAuthenticationFilter {

        public JwtAuthenticationFilter() throws Exception {
            super(authenticationManager());
        }

        @Override
        protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
            String token = request.getHeader("token");
            if (ObjectUtil.isNotEmpty(token)) {
                //1.获取token里面的用户角色
                JWT jwt = JWTUtil.parseToken(token);
                JSONObject jsonObject = JSONUtil.toBean(jwt.getPayload().toString(), JSONObject.class);
                JSONArray roles = jsonObject.getJSONArray("roles");
                //2. 放入到角色列表中
                List<GrantedAuthority> grantedAuthorityList = new ArrayList<>();
                roles.forEach(role -> {
                    SimpleGrantedAuthority simpleGrantedAuthority = new SimpleGrantedAuthority(role.toString());
                    grantedAuthorityList.add(simpleGrantedAuthority);
                });
                //3.把用户权限加到列表
                JSONArray permissions = jsonObject.getJSONArray("permissions");
                permissions.forEach(permission -> {
                    SimpleGrantedAuthority simpleGrantedAuthority = new SimpleGrantedAuthority(permission.toString());
                    grantedAuthorityList.add(simpleGrantedAuthority);
                });
                //4. 实例化一个该用户的 token 票据
                UsernamePasswordAuthenticationToken atoken =
                        new UsernamePasswordAuthenticationToken(jsonObject.get("id"), null, grantedAuthorityList);
                //5. 把票据放到Security上下文里
                SecurityContextHolder.getContext().setAuthentication(atoken);
            }
            //执行链接着继续走
            chain.doFilter(request, response);
        }
    }
}
